package com.xmy.cultivate.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xmy.cultivate.entity.*;
import com.xmy.cultivate.entity.views.ChaPlan;
import com.xmy.cultivate.entity.views.MathChaPlan;
import com.xmy.cultivate.entity.views.VsStoreData;
import com.xmy.cultivate.feign.math.IFeiMathFeignClient;
import com.xmy.cultivate.feign.physics_outside.IPhysicsFeignClient;
import com.xmy.cultivate.mapper.StoreGoodsMapper;
import com.xmy.cultivate.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xmy.cultivate.util.*;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 物次库存 服务实现类
 * </p>
 *
 * @author hpiggy
 * @since 2024-07-30
 */
@Service
public class StoreGoodsServiceImpl extends ServiceImpl<StoreGoodsMapper, StoreGoods> implements IStoreGoodsService {

    @Autowired
            @Lazy
    StoreGoodsMapper storeGoodsMapper;

    @Autowired
            @Lazy
    IStoreGoodsOrderService iStoreGoodsOrderService;

    @Autowired
    IStoreGoodsAffirmService iStoreGoodsAffirmService;

    @Autowired
    IStoreGoodsBatchService iStoreGoodsBatchService;

    @Autowired
    IStoreGoodsBatchDetailService iStoreGoodsBatchDetailService;

    @Autowired
    IStoreGoodsOrderBatchService iStoreGoodsOrderBatchService;

    @Autowired
    IStoreGoodsTypeService iStoreGoodsTypeService;

    @Autowired
    IFeiMathFeignClient iFeiMathFeignClient;

    @Autowired
    IPhysicsFeignClient iPhysicsFeignClient;

    @Autowired
    private IdWorker idWorker;

    @Override
    public IPage<CourseType> getClassTypeList(IPage<?> page, Integer yearPart, Integer quarterNum, Long schoolId, Long subjectsId, Integer yearClassId, Long classTypeId, Long goodsTypeId){
        return storeGoodsMapper.getClassTypeList(page,yearPart,quarterNum,schoolId,subjectsId,yearClassId,classTypeId,goodsTypeId);
    }

    @Override
    public Integer getMaxLessonNum(Integer yearPart, Integer quarterNum, Long schoolId, Long subjectsId, Integer yearClassId, Long classTypeId, Long goodsTypeId){
       return storeGoodsMapper.getMaxLessonNum(yearPart,quarterNum,schoolId,subjectsId,yearClassId,classTypeId,goodsTypeId);
    }

    @Override
    public List<StoreGoods> getStoreGoodsList(Integer yearPart, Integer quarterNum, Long schoolId, Long subjectsId, Integer yearClassId, Long classTypeId, Long goodsTypeId, Integer lessonType){
        return storeGoodsMapper.getStoreGoodsList(yearPart,quarterNum,schoolId,subjectsId,yearClassId,classTypeId,goodsTypeId,lessonType);
    }

    /**
     * 入库
     * @param storeGoods
     * @return
     */
    @Override
    @Transactional
    public boolean addStoreGoods(StoreGoods storeGoods){
        List<StoreGoodsOrder> storeGoodsOrderList = new ArrayList<>();
        LocalDateTime dateTimeNow = LocalDateTime.now().withNano(0);
        for (StoreGoodsOrder storeGoodsOrder:storeGoods.getStoreGoodsOrderList()){
            if (storeGoodsOrder.getGoodsCount() == null){
                continue;
            }
            if (storeGoodsOrder.getGoodsCount().compareTo(0)>0){
                storeGoodsOrder.setId(idWorker.nextId());
                storeGoodsOrder.setName(storeGoods.getName());
                storeGoodsOrder.setGoodsTypeId(storeGoods.getGoodsTypeId());
                storeGoodsOrder.setYearPart(storeGoods.getYearPart());
                storeGoodsOrder.setQuarterNum(storeGoods.getQuarterNum());
                storeGoodsOrder.setSchoolId(storeGoods.getSchoolId());
                storeGoodsOrder.setClassTypeId(storeGoods.getClassTypeId());
                storeGoodsOrder.setSubjectsId(storeGoods.getSubjectsId());
                storeGoodsOrder.setYearClassId(storeGoods.getYearClassId());
                storeGoodsOrder.setLessonType(storeGoods.getLessonType());
                storeGoodsOrder.setType(storeGoods.getType());
                storeGoodsOrder.setBatchNum(storeGoods.getBatchNum());
                storeGoodsOrder.setCreatedAt(dateTimeNow);
                storeGoodsOrder.setStatus(1);
                if (this.addAndUpdate(storeGoodsOrder)){
                    storeGoodsOrderList.add(storeGoodsOrder);
                }
            }
        }
        if (storeGoodsOrderList.size()>0){
            //iStoreGoodsOrderService.saveBatch(storeGoodsOrderList);
            LocalDateTime localDateTime = LocalDateTime.now().withNano(0);

            StoreGoodsOrderBatch storeGoodsOrderBatch = new StoreGoodsOrderBatch();
            BeanUtils.copyProperties(storeGoods,storeGoodsOrderBatch);
            storeGoodsOrderBatch.setId(storeGoods.getBatchNum());
            StoreGoodsAffirm storeGoodsAffirm = new StoreGoodsAffirm();
            storeGoodsAffirm.setOrderId(storeGoodsOrderBatch.getId());
            if (storeGoodsOrderBatch.getType().equals(1)){
                //入库
                storeGoodsAffirm.setType(3);
                storeGoodsOrderBatch.setStatus(3);
            }else if (storeGoodsOrderBatch.getType().equals(2)){
                //加订
                storeGoodsAffirm.setType(1);
                storeGoodsOrderBatch.setStatus(1);
            }
            storeGoodsAffirm.setCreatedAt(localDateTime);
            iStoreGoodsOrderBatchService.save(storeGoodsOrderBatch);
            iStoreGoodsAffirmService.save(storeGoodsAffirm);
            iStoreGoodsOrderService.saveBatch(storeGoodsOrderList);
        }
        return true;
    }

    @Override
    @Transactional
    public boolean addStoreGoodsBatch(@NotNull StoreGoodsBatch storeGoodsBatch){
        for (StoreGoods storeGoods:storeGoodsBatch.getStoreGoodsList()){
            StoreGoodsType storeGoodsType = iStoreGoodsTypeService.getById(2L);
            storeGoods.setGoodsTypeId(storeGoodsType.getId());
            storeGoods.setName(storeGoodsType.getName());
            storeGoods.setType(2);//加订为2
            storeGoods.setBatchNum(idWorker.nextId());//批次号
            this.addStoreGoods(storeGoods);
        }
        return true;
    }

    /**
     * 确认下单
     * @param storeGoods
     * @return
     */
    @Override
    @Transactional
    public boolean affirmAddOrder(StoreGoods storeGoods){
        StoreGoodsBatch storeGoodsBatch = new StoreGoodsBatch();
        if (storeGoods.getStoreGoodsOrderList().size()>0){
            Integer i=0;
            for (StoreGoodsOrder storeGoodsOrder:storeGoods.getStoreGoodsOrderList()){
                if (i>0){
                    continue;
                }
                StoreGoodsOrderBatch storeGoodsOrderBatch = iStoreGoodsOrderBatchService.getById(storeGoodsOrder.getId());
                storeGoods.setYearPart(storeGoodsOrderBatch.getYearPart());
                storeGoods.setQuarterNum(storeGoodsOrderBatch.getQuarterNum());
                storeGoods.setSubjectsId(storeGoodsOrderBatch.getSubjectsId());
                storeGoodsOrderBatch.setStatus(2);
                i++;
            }
        }

        Integer maxNum = iStoreGoodsBatchService.getMaxBatchNum(storeGoods.getYearPart(),storeGoods.getQuarterNum());
        maxNum++;
        storeGoodsBatch.setBatchNum(maxNum);
        storeGoodsBatch.setYearPart(storeGoods.getYearPart());
        storeGoodsBatch.setQuarterNum(storeGoods.getQuarterNum());
        storeGoodsBatch.setSubjectsId(storeGoods.getSubjectsId());
        Long batchNo = idWorker.nextId();
        storeGoodsBatch.setBatchNo(batchNo.toString());
        iStoreGoodsBatchService.save(storeGoodsBatch);
        StoreGoodsAffirm storeGoodsAffirm = new StoreGoodsAffirm();
        LocalDateTime dateTimeNow = LocalDateTime.now().withNano(0);
        for (StoreGoodsOrder storeGoodsOrder:storeGoods.getStoreGoodsOrderList()){
            StoreGoodsOrderBatch storeGoodsOrderBatch = iStoreGoodsOrderBatchService.getById(storeGoodsOrder.getId());
            if (!storeGoodsOrderBatch.getStatus().equals(1)){
                continue;
            }
            storeGoodsOrderBatch.setStatus(2);//0未确认，1已确认、未下单，2已下单，3已入库
            iStoreGoodsOrderBatchService.updateById(storeGoodsOrderBatch);

            StoreGoodsBatchDetail storeGoodsBatchDetail = new StoreGoodsBatchDetail();
            storeGoodsBatchDetail.setGoodsBatchId(storeGoodsBatch.getId());
            storeGoodsBatchDetail.setGoodsOrderBatchId(storeGoodsOrderBatch.getId());
            iStoreGoodsBatchDetailService.save(storeGoodsBatchDetail);

            UpdateWrapper<StoreGoodsOrder> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("batch_num", storeGoodsOrder.getId());
            updateWrapper.set("status",2);
            iStoreGoodsOrderService.update(updateWrapper);

            storeGoodsAffirm = new StoreGoodsAffirm();
            storeGoodsAffirm.setOrderId(storeGoodsOrderBatch.getId());
            storeGoodsAffirm.setType(2);
            storeGoodsAffirm.setCreatedAt(dateTimeNow);
            iStoreGoodsAffirmService.save(storeGoodsAffirm);
        }
        storeGoodsAffirm = new StoreGoodsAffirm();
        storeGoodsAffirm.setOrderId(storeGoodsBatch.getId());
        storeGoodsAffirm.setType(2);
        storeGoodsAffirm.setCreatedAt(dateTimeNow);
        iStoreGoodsAffirmService.save(storeGoodsAffirm);
        return true;
    }


    /**
     * 选择未入库的下单信息确认入库
     * @param storeGoods
     * @return
     */
    @Override
    @Transactional
    public boolean affirmAddStoreGoods(StoreGoods storeGoods){
        for (StoreGoodsOrder storeGoodsOrderParam:storeGoods.getStoreGoodsOrderList()){
            StoreGoodsOrderBatch storeGoodsOrderBatch = iStoreGoodsOrderBatchService.getById(storeGoodsOrderParam.getId());
            storeGoodsOrderBatch.setStatus(3);//0未确认，1已确认、未下单，2已下单，3已入库
            QueryWrapper<StoreGoodsOrder> storeGoodsOrderQueryWrapper = new QueryWrapper<>();
            storeGoodsOrderQueryWrapper.eq("batch_num",storeGoodsOrderBatch.getId());
            List<StoreGoodsOrder> storeGoodsOrderList = iStoreGoodsOrderService.list(storeGoodsOrderQueryWrapper);
            for (StoreGoodsOrder storeGoodsOrder:storeGoodsOrderList){
                this.affirmAddAndUpdate(storeGoodsOrder);
                storeGoodsOrder.setStatus(3);
                iStoreGoodsOrderService.updateById(storeGoodsOrder);
            }
            iStoreGoodsOrderBatchService.updateById(storeGoodsOrderBatch);

            StoreGoodsAffirm storeGoodsAffirm = new StoreGoodsAffirm();
            storeGoodsAffirm.setOrderId(storeGoodsOrderBatch.getId());
            storeGoodsAffirm.setType(3);//1加订确认，2下单，3入库
            iStoreGoodsAffirmService.save(storeGoodsAffirm);
        }
        return true;
    }




    public boolean addAndUpdate(StoreGoodsOrder storeGoodsOrder){
        QueryWrapper<StoreGoods> storeGoodsQueryWrapper = new QueryWrapper<>();
        storeGoodsQueryWrapper.eq("year_part",storeGoodsOrder.getYearPart());
        storeGoodsQueryWrapper.eq("quarter_num",storeGoodsOrder.getQuarterNum());
        storeGoodsQueryWrapper.eq("goods_type_id",storeGoodsOrder.getGoodsTypeId());
        storeGoodsQueryWrapper.eq("school_id",storeGoodsOrder.getSchoolId());
        storeGoodsQueryWrapper.eq("class_type_id",storeGoodsOrder.getClassTypeId());
        storeGoodsQueryWrapper.eq("subjects_id",storeGoodsOrder.getSubjectsId());
        storeGoodsQueryWrapper.eq("year_class_id",storeGoodsOrder.getYearClassId());
        storeGoodsQueryWrapper.eq("lesson_type",storeGoodsOrder.getLessonType());
        storeGoodsQueryWrapper.eq("lesson_num",storeGoodsOrder.getLessonNum());
        storeGoodsQueryWrapper.last("limit 1");
        StoreGoods storeGoods = this.getOne(storeGoodsQueryWrapper);
        if (storeGoods == null){
            storeGoods = new StoreGoods();
            BeanUtils.copyProperties(storeGoodsOrder,storeGoods);
            storeGoods.setPrestoreCount(0);
            storeGoods.setGoodsCount(0);
        }
        if (storeGoodsOrder.getType().equals(1)){//入库
            storeGoods.setGoodsCount(storeGoods.getGoodsCount()+storeGoodsOrder.getGoodsCount());
            //入库，如果有预存数据，减掉预存数量
            /*if (storeGoods.getPrestoreCount()>0){
                Integer prestoreCount = storeGoods.getPrestoreCount();
                prestoreCount = prestoreCount - storeGoodsOrder.getGoodsCount();
                if (prestoreCount<0){
                    prestoreCount = 0;
                }
                storeGoods.setPrestoreCount(prestoreCount);
            }*/
        }else if (storeGoodsOrder.getType().equals(2)){//确认加订
            storeGoods.setPrestoreCount(storeGoods.getPrestoreCount()+storeGoodsOrder.getGoodsCount());
        }else {
            return false;
        }
        boolean rs = this.saveOrUpdate(storeGoods);
        if (rs){
            return true;
        }else {
            return false;
        }
    }

    /**
     * 确认入库添加与信息
     * @param storeGoodsOrder
     * @return
     */
    public boolean affirmAddAndUpdate(StoreGoodsOrder storeGoodsOrder){
        QueryWrapper<StoreGoods> storeGoodsQueryWrapper = new QueryWrapper<>();
        storeGoodsQueryWrapper.eq("year_part",storeGoodsOrder.getYearPart());
        storeGoodsQueryWrapper.eq("quarter_num",storeGoodsOrder.getQuarterNum());
        storeGoodsQueryWrapper.eq("goods_type_id",storeGoodsOrder.getGoodsTypeId());
        storeGoodsQueryWrapper.eq("school_id",storeGoodsOrder.getSchoolId());
        storeGoodsQueryWrapper.eq("class_type_id",storeGoodsOrder.getClassTypeId());
        storeGoodsQueryWrapper.eq("subjects_id",storeGoodsOrder.getSubjectsId());
        storeGoodsQueryWrapper.eq("year_class_id",storeGoodsOrder.getYearClassId());
        storeGoodsQueryWrapper.eq("lesson_type",storeGoodsOrder.getLessonType());
        storeGoodsQueryWrapper.eq("lesson_num",storeGoodsOrder.getLessonNum());
        storeGoodsQueryWrapper.last("limit 1");
        StoreGoods storeGoods = this.getOne(storeGoodsQueryWrapper);
        if (storeGoods == null){
            storeGoods = new StoreGoods();
            BeanUtils.copyProperties(storeGoodsOrder,storeGoods);
            storeGoods.setPrestoreCount(0);
            storeGoods.setGoodsCount(storeGoodsOrder.getGoodsCount());
        }else {
            storeGoods.setGoodsCount(storeGoodsOrder.getGoodsCount());
            Integer prestoreCount = storeGoods.getPrestoreCount() - storeGoodsOrder.getGoodsCount();
            if (prestoreCount<0){
                prestoreCount = 0;
            }
            storeGoods.setPrestoreCount(prestoreCount);
        }
        boolean rs = this.saveOrUpdate(storeGoods);
        if (rs){
            return true;
        }else {
            return false;
        }
    }

    @Override
    public List<Map<String, Object>> needOrderExport(Integer yearPart, Integer quarterNum, Long schoolId, Integer lessonType, Long subjectsId, Integer yearClassId, Long classTypeId, Long goodsTypeId) {
        Map<String, Object> map = new HashMap<>();
        List<Map<String, Object>> mapList = new ArrayList<>();
        if (subjectsId.equals(2L)) {
            map = iFeiMathFeignClient.getNeedOrder(-1, -1, yearPart, quarterNum, schoolId, lessonType, subjectsId, yearClassId, classTypeId, goodsTypeId);
            mapList = this.getNeedOrderExportData(map);

        } else {
            map = iPhysicsFeignClient.getNeedOrder(-1, -1, yearPart, quarterNum, schoolId, lessonType, subjectsId, yearClassId, classTypeId, goodsTypeId);
        }
        return mapList;
    }

    public List<Map<String, Object>> getNeedOrderExportData(Map<String, Object> map) {
        // 当前最大课次
        Integer maxLessonNum = (Integer) map.get("maxLessonNum");
        // 当前校区班型条数
        String classTypeListStr = JsonUtils.objectToJson(map.get("classTypeList"));
        PageResult pageResult = JsonUtils.jsonToPojo(classTypeListStr, PageResult.class);
        String rowsStr = JsonUtils.objectToJson(pageResult.getRows());
        List<VsStoreData> vsStoreDataList = JsonUtils.jsonToList(rowsStr, VsStoreData.class);
        String listStr = JsonUtils.objectToJson(map.get("list"));
        List<ChaPlan> mathChaPlanList = JsonUtils.jsonToList(listStr, ChaPlan.class);
        List<Map<String, Object>> mapList = new ArrayList<>();
        for (VsStoreData vsStoreData : vsStoreDataList) {
            Map<String, Object> mapItem = new HashMap<>();
            mapItem.put("schoolName", vsStoreData.getSchoolName());
            mapItem.put("yearClassName", CommonUtil.getYearClassNameForId(vsStoreData.getYearClassId()));
            mapItem.put("classTypeName", vsStoreData.getClassTypeName());
            String lessonNameFinal = "lessonNum";
            for (Integer i = 1; i <= maxLessonNum; i++) {
                Integer finalI = i;
                String lessonName = lessonNameFinal + i;
                Integer drawUpCount = 0;
                Optional<ChaPlan> chaPlanOptional = mathChaPlanList.stream()
                        .filter(mathTemp -> mathTemp.getSchoolId().equals(vsStoreData.getSchoolId()))
                        .filter(mathTemp -> mathTemp.getYearClassId().equals(vsStoreData.getYearClassId()))
                        .filter(mathTemp -> mathTemp.getClassTypeId().equals(vsStoreData.getClassTypeId()))
                        .filter(mathTemp -> mathTemp.getLessonNum().equals(finalI)).findFirst();
                if (chaPlanOptional != null && chaPlanOptional.isPresent()) {
                    ChaPlan chaPlan = chaPlanOptional.get();
                    drawUpCount = chaPlan.getDrawUpCount();
                }
                mapItem.put(lessonName, drawUpCount);
            }
            mapList.add(mapItem);
        }
        return mapList;
    }

}
